<template>
  <div>
    <el-table
      border
      style="margin-bottom: 20px;"
      :data="menuPermissionList"
      :expand-row-keys="expandKeys"
      row-key="id"
    >
      <el-table-column prop="name" label="名称" />
      <el-table-column prop="code" label="权限值" />

      <el-table-column prop="toCode" label="跳转权限值" />

      <el-table-column label="操作">
        <template slot-scope="{ row }">
          <HintButton
            :disabled="row.level === 4"
            type="primary"
            icon="el-icon-plus"
            size="mini"
            @click="toAddPermission(row)"
            :title="getAddTitle(row.level)"
          />

          <HintButton
            type="primary"
            icon="el-icon-edit"
            size="mini"
            :disabled="row.level === 1"
            @click="toUpdatePermission(row)"
            :title="row.level === 4 ? '修改功能' : '修改菜单'"
          />

          <HintButton
            :disabled="row.level === 1"
            type="danger"
            icon="el-icon-delete"
            size="mini"
            @click="removePermission(row)"
            title="删除"
          />
        </template>
      </el-table-column>
    </el-table>

    <el-dialog
      :visible.sync="dialogPermissionVisible"
      :title="dialogTitle"
      @close="resetData"
    >
      <el-form
        ref="permission"
        :model="permission"
        :rules="permissionRules"
        label-width="120px"
      >
        <el-form-item label="名称" prop="name">
          <el-input v-model="permission.name" />
        </el-form-item>

        <el-form-item label="功能权限值" prop="code">
          <el-input v-model="permission.code" />
        </el-form-item>

        <el-form-item
          label="跳转路由权限值"
          prop="toCode"
          v-if="permission.level === 4"
        >
          <el-input v-model="permission.toCode" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="resetData">取 消</el-button>
        <el-button type="primary" @click="addOrUpdatePermission"
          >确 定</el-button
        >
      </div>
    </el-dialog>
  </div>
</template>

<script>
// 菜单权限校验的规则
const menuRules = {
  name: [{ required: true, message: "名称必须输入" }],
  code: [{ required: true, message: "权限值必须输入" }]
};

// 按钮功能权限校验的规则
const btnRules = {
  name: [{ required: true, message: "名称必须输入" }],
  code: [{ required: true, trigger: "blur", message: "功能权限值必须输入" }]
};

export default {
  name: "PermissionList",

  data() {
    return {
      menuPermissionList: [], // 菜单列表
      expandKeys: [], // 需要自动展开的项
      dialogPermissionVisible: false, // 是否显示菜单权限的对话框
      permission: {
        // 要操作的菜单权限对象
        level: 0, // 级别
        name: "", // 名称
        code: "", // 权限值
        toCode: "" // 要跳转的权限值
      }
    };
  },

  computed: {
    // 动态计算得到对话框的标题
    dialogTitle() {
      const { id, level } = this.permission;
      if (id) {
        return level === 4 ? "修改功能" : "修改菜单";
      } else {
        return level === 4 ? "添加功能" : "添加菜单";
      }
    },

    // 根据权限的等级计算确定校验规则
    permissionRules() {
      return this.permission.level === 4 ? btnRules : menuRules;
    }
  },

  mounted() {
    // 获取权限菜单数据列表
    this.fetchPermissionList();
  },

  methods: {
    // 根据级别得到要显示的添加对话框的标题
    getAddTitle(level) {
      if (level === 1 || level === 2) {
        return "添加菜单";
      } else if (level === 3) {
        return "添加功能";
      }
    },

    // 请求获取权限菜单数据列表
    async fetchPermissionList() {
      // 请求获取所有权限列表
      const result = await this.$API.permission.getPermissionList();
      // 显示包含'全部数据'的列表
      this.menuPermissionList = result.data.children;
      // 默认展开全部数据的子列表
      this.expandKeys = [this.menuPermissionList[0].id];
    },

    // 显示添加权限的界面
    toAddPermission(row) {
      // 显示对话框
      this.dialogPermissionVisible = true;
      // 指定父权限的id
      this.permission.pid = row.id;
      // 指定等级
      this.permission.level = row.level + 1;
      // 指定类型
      this.permission.type = this.permission.level === 4 ? 2 : 1;
      // 清除校验(必须在界面更新之后)
      this.$nextTick(() => this.$refs.permission.clearValidate());
    },

    // 显示路由或按钮更新的对话框
    toUpdatePermission(row) {
      // 显示对话框
      this.dialogPermissionVisible = true;
      // 使用浅拷贝
      this.permission = { ...row };
      // 清除校验(必须在界面更新之后)
      this.$nextTick(() => this.$refs.permission.clearValidate());
    },

    // 删除某个权限节点
    removePermission(permission) {
      this.$confirm("此操作将永久删除该记录, 是否继续?", "提示", {
        type: "warning"
      })
        .then(async () => {
          // 请求删除指定权限节点
          const result = await this.$API.permission.removePermission(
            permission.id
          );
          // 提示
          this.$message.success(result.message || "删除成功!");
          // 重新获取所有权限节点列表
          this.fetchPermissionList();
        })
        .catch(error => {
          if (error === "cancel") {
            this.$message({
              type: "info",
              message: "已取消删除"
            });
          }
        });
    },

    // 添加或更新功能权限
    addOrUpdatePermission() {
      // 表单校验
      this.$refs.permission.validate(async valid => {
        // 如果通过了
        if (valid) {
          const { permission } = this;
          const { id } = permission;
          // 请求添加或更新权限
          const result = await this.$API.permission[
            id ? "updatePermission" : "addPermission"
          ](permission);
          // 提示
          this.$message.success(
            result.message || `${id ? "修改" : "添加"}成功!`
          );
          // 重置数据
          this.resetData();
          // 重新获取列表
          this.fetchPermissionList();
        }
      });
    },

    // 重置数据
    resetData() {
      this.dialogPermissionVisible = false;
      this.permission = {
        level: 0,
        name: "",
        code: "",
        toCode: ""
      };
    }
  }
};
</script>
